﻿// This software is the confidential and proprietary information of NetBay.
// Such confidential information should not be disclosed.
// NetBay copyright(c) 2012

#region

using System;
using System.Collections.Generic;
using System.IO;
using System.IO.IsolatedStorage;
using System.Linq;
using System.Linq.Expressions;
using System.Runtime.Serialization;
using System.ServiceModel.DomainServices.Client;
using NetBay.Core.BusinessEntities;
using NetBay.Core.BusinessEntities.Barcodes;
using NetBay.Core.Encryption.Licensing;
using Rio.Applications.Web.Services;
using Rio.Framework.Pages.AppCode.Enums;
using Rio.Framework.Pages.Helpers;
using Rio.Framework.Pages.Manager;

#endregion

namespace Rio.Framework.Pages.Context
{
    /// <summary>
    /// 
    /// </summary>
    public static class GlobalWebContext
    {
        #region Readonly & Static Fields

        private static BusinessEntitiesDomainContext _context;
        private static CopyPasteClipboard _manager;

        #endregion

        #region Class Properties

        /// <summary>
        /// Gets the business entities domain context.
        /// </summary>
        /// <value>The business entities domain context.</value>
        public static BusinessEntitiesDomainContext BusinessEntitiesDomainContext
        {
            get
            {
                if (_context == null)
                {
                    _context = new BusinessEntitiesDomainContext();
                    ((WebDomainClient<BusinessEntitiesDomainContext.IBusinessEntitiesDomainServiceContract>)
                     _context.DomainClient).ChannelFactory.Endpoint.Binding.SendTimeout = new TimeSpan(0, 10, 0);
                    ((WebDomainClient<BusinessEntitiesDomainContext.IBusinessEntitiesDomainServiceContract>)
                     _context.DomainClient).ChannelFactory.Endpoint.Binding.ReceiveTimeout = new TimeSpan(0, 10, 0);
                }
                return _context;
            }
        }

        /// <summary>
        /// Gets the client scan.
        /// </summary>
        /// <value>The client scan.</value>
        public static bool ClientScan
        {
            get
            {
                if (CurrentUser != null)
                {
                    return CurrentUser.CTX_ClientScan;
                }
                return false;
            }
        }

        /// <summary>
        /// Get copy past manager
        /// </summary>
        public static CopyPasteClipboard CopyPasteManager
        {
            get
            {
                if (_manager == null)
                    _manager = new CopyPasteClipboard();
                return _manager;
            }
        }

        /// <summary>
        /// Gets the culture.
        /// </summary>
        /// <value>The culture.</value>
        public static string Culture
        {
            get { return RioAppSettings["Rio.Applications.Web.DefaultCulture"]; }
        }

        /// <summary>
        /// Gets a value indicating whether [add flow index folder in first].
        /// </summary>
        /// <value>
        /// <c>true</c> if [add flow index folder in first]; otherwise, <c>false</c>.
        /// </value>
        public static bool AddFlowIndexInFirst
        {
            get
            {
                if (RioAppSettings.ContainsKey("AddFlowIndexInFirst"))
                {
                    return Convert.ToBoolean(RioAppSettings["AddFlowIndexInFirst"]);
                }
                return false;
            }
        }

        /// <summary>
        /// Gets a value indicating whether [keep criteria on flow indexing].
        /// </summary>
        /// <value>
        /// <c>true</c> if [keep criteria on flow indexing]; otherwise, <c>false</c>.
        /// </value>
        public static bool KeepCriteriaOnFlowIndexing
        {
            get
            {
                if (RioAppSettings.ContainsKey("KeepCriteriaOnFlowIndexing"))
                {
                    return Convert.ToBoolean(RioAppSettings["KeepCriteriaOnFlowIndexing"]);
                }
                return false;
            }
        }

        /// <summary>
        /// Gets a value indicating whether [select all image after import].
        /// </summary>
        /// <value>
        /// <c>true</c> if [select all image after import]; otherwise, <c>false</c>.
        /// </value>
        public static bool? SelectAllImageAfterImport
        {
            get
            {
                if (RioAppSettings.ContainsKey("SelectAllImageAfterImport"))
                {
                    return Convert.ToBoolean(RioAppSettings["SelectAllImageAfterImport"]);
                }
                return null;
            }
        }

        /// <summary>
        /// Get current user
        /// </summary>
        public static User CurrentUser
        {
            get { return LoginManager.Instance.CurrentUser; }
        }

        /// <summary>
        /// Gets or sets the license terms.
        /// </summary>
        /// <value>
        /// The license terms.
        /// </value>
        private static LicenseTerms _licenseTerms;
        public static LicenseTerms LicenseTerms
        {
            get
            {
                if (_licenseTerms == null)
                {
                    _licenseTerms = new LicenseTerms()
                               {
                                   LicenseType = LicenseType.Standard
                               };
                }
                return _licenseTerms;
            }
            set { _licenseTerms = value; }
        }

        /// <summary>
        /// Gets the parameter storage.
        /// </summary>
        /// <value>The parameter storage.</value>
        public static string ParameterStorage
        {
            get { return CurrentUser.CTX_ParameterStorage; }
        }

        /// <summary>
        /// Gets the parameter storage thumbnail.
        /// </summary>
        /// <value>The parameter storage thumbnail.</value>
        public static string ParameterStorageThumbnail
        {
            get { return CurrentUser.CTX_ParameterStorageThumbnail; }
        }

        public static IDictionary<string, string> RioAppSettings { get; set; }

        #endregion

        #region Class Methods

        /// <summary>
        /// Get if user is administrator
        /// </summary>
        /// <returns>right</returns>
        public static bool GetIsAdministrator(FolderType P_oFolderType)
        {
            return UserCan(P_oFolderType, p => p.IsAdministrator);
        }

        /// <summary>
        /// Get if User can delete
        /// </summary>
        /// <returns>right to apply</returns>
        public static bool GetUserCanDelete(FolderType P_oFolderType)
        {
            return UserCan(P_oFolderType, p => p.CanDelete);
        }

        /// <summary>
        /// Get if User can download
        /// </summary>
        /// <returns>right to apply</returns>
        public static bool GetUserCanDownload(FolderType P_oFolderType)
        {
            return UserCan(P_oFolderType, p => p.CanDownload);
        }

        /// <summary>
        /// Gets the user can process barcode.
        /// </summary>
        /// <param name="barcodes">The barcodes.</param>
        /// <returns></returns>
        public static bool GetUserCanProcessBarcode(List<Barcode> barcodes)
        {
            bool result = false;
            if(barcodes != null && barcodes.Count > 0 )
            {
                foreach (var barcode in barcodes)
                {
                    var bc = (BarcodeFolderSeparator)barcode.BarCodeSeparatorList.FirstOrDefault();
                    if(bc.CorrespondenceFolder)
                    {
                        result = GetUserCanImport(bc.OrganizationId, bc.FolderTypeId);
                        if(result)
                        {
                            break;
                        }
                    }
                }
            }

            return result;
        }

        /// <summary>
        /// Get if User can import documents
        /// </summary>
        /// <returns>right to apply</returns>
        public static bool GetUserCanImport(Organization P_oSelectedOrganisation, FolderType P_oSelectedFolderType)
        {
            //Depends of Organization selected item
            if ((P_oSelectedOrganisation != null) || (P_oSelectedFolderType != null))
            {
                OrganizationComparer L_oOrganisationComparer = new OrganizationComparer();
                FolderTypeComparer L_oFolderTypeComparer = new FolderTypeComparer();

                foreach (Group UserGroup in CurrentUser.GroupList)
                {
                    if (UserGroup.OrganizationList.Contains(P_oSelectedOrganisation, L_oOrganisationComparer))
                    {
                        if (UserGroup.FolderTypeRigthList.Contains(P_oSelectedFolderType, L_oFolderTypeComparer))
                        {
                            if ((UserGroup.CanReorganize) || (UserGroup.CanConsult))
                            {
                                if (UserGroup.CanScann)
                                {
                                    return true;
                                }
                            }
                        }
                    }
                }
            }

            return false;
        }

        /// <summary>
        /// Gets the user can import.
        /// </summary>
        /// <param name="P_oSelectedOrganisation">The p_o selected organisation.</param>
        /// <param name="P_oSelectedFolderType">Type of the p_o selected folder.</param>
        /// <returns></returns>
        public static bool GetUserCanImport(long P_oSelectedOrganisation, long P_oSelectedFolderType)
        {
            //Depends of Organization selected item
            foreach (Group UserGroup in CurrentUser.GroupList)
            {
                if (UserGroup.OrganizationList.Any(o => o.Identifier == P_oSelectedOrganisation))
                {
                    if (UserGroup.FolderTypeRigthList.Any(p => p.Identifier == P_oSelectedFolderType))
                    {
                        if ((UserGroup.CanReorganize) || (UserGroup.CanConsult))
                        {
                            if (UserGroup.CanScann)
                            {
                                return true;
                            }
                        }
                    }
                }
            }

            return false;
        }

        /// <summary>
        /// Get if User can import
        /// </summary>
        /// <returns>right to apply</returns>
        public static bool GetUserCanImport()
        {
            if (CurrentUser != null)
            {
                foreach (Group grp in CurrentUser.GroupList)
                {
                    if (grp.IsAdministrator)
                    {
                        return true;
                    }
                    if (grp.CanScann)
                    {
                        return true;
                    }
                }
            }
            return false;
        }

        /// <summary>
        /// Get if User can modify folder
        /// </summary>
        /// <returns>right to apply</returns>
        public static bool GetUserCanModify(FolderType P_oFolderType)
        {
            return UserCan(P_oFolderType, p => p.CanReorganize);
        }

        /// <summary>
        /// Get if User can print
        /// </summary>
        /// <returns>right to apply</returns>
        public static bool GetUserCanPrint(FolderType P_oFolderType)
        {
            return UserCan(P_oFolderType, p => p.CanPrint);
        }

        /// <summary>
        /// Get if User can scann
        /// </summary>
        /// <returns>right to apply</returns>
        public static bool GetUserCanScann(FolderType P_oFolderType)
        {
            return UserCan(P_oFolderType, p => p.CanScann);
        }

        /// <summary>
        /// Get if User can send mail
        /// </summary>
        /// <returns>right to apply</returns>
        public static bool GetUserCanSendMail(FolderType P_oFolderType)
        {
            return UserCan(P_oFolderType, p => p.CanSendEmail);
        }

        /// <summary>
        /// Gets the user can trash.
        /// </summary>
        /// <param name="P_oFolderType">Type of the p_o folder.</param>
        /// <returns></returns>
        public static bool GetUserCanTrash(FolderType P_oFolderType)
        {
            return UserCan(P_oFolderType, p => p.CanTrash);
        }

        /// <summary>
        /// Get if User can valid workflow
        /// </summary>
        /// <returns>right to apply</returns>
        public static bool GetUserCanValidFlow(FolderType P_oFolderType)
        {
            return UserCan(P_oFolderType, p => p.CanFlowValidation);
        }

        /// <summary>
        /// Check if organization contains foldertype which can be display by mode
        /// </summary>
        /// <param name="org">Organization to verify</param>
        /// <returns></returns>
        public static bool OrganizationHaveFolderTypeRight(Organization org, AppDisplayMode mode)
        {
            FolderTypeComparer L_oFolderTypeComparer = new FolderTypeComparer();

            foreach (FolderType FolderTypeInOrga in org.FolderTypesList)
            {
                foreach (Group UserGroup in GlobalWebContext.CurrentUser.GroupList)
                {
                    if (UserGroup.FolderTypeRigthList.Contains(FolderTypeInOrga, L_oFolderTypeComparer))
                    {
                        if (mode == AppDisplayMode.Search)
                        {
                            if ((UserGroup.CanReorganize) || (UserGroup.CanConsult))
                            {
                                return true;
                            }
                        }
                        else if (mode == AppDisplayMode.Import || mode == AppDisplayMode.AddDocument)
                        {
                            if ((UserGroup.CanScann) || (UserGroup.CanMassImport))
                            {
                                return true;
                            }
                        }
                        else if (mode == AppDisplayMode.Flow)
                        {
                            if ((UserGroup.CanScann) || (UserGroup.CanMassImport))
                            {
                                //specific flow
                                if (!org.FolderTypesList.Any(folderType => folderType.Table.Equals("TD004")))
                                {
                                    return true;
                                }
                            }
                        }
                        else if (mode == AppDisplayMode.Admin)
                        {
                            if ((UserGroup.IsAdministrator))
                            {
                                return true;
                            }
                        }
                    }
                }
            }

            return false;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="filename"></param>
        /// <returns></returns>
        public static User Retrieve(string filename)
        {
            User obj = default(User);
            IsolatedStorageFile appStore = IsolatedStorageFile.GetUserStoreForSite();
            if (appStore.FileExists(filename))
            {
                using (IsolatedStorageFileStream fileStream = appStore.OpenFile(filename, FileMode.Open))
                {
                    DataContractSerializer serializer = new DataContractSerializer(typeof (User));
                    obj = (User) serializer.ReadObject(fileStream);
                }
            }

            return obj;
        }

        /// <summary>
        /// Users the can.
        /// </summary>
        /// <param name="folderType">Type of the folder.</param>
        /// <param name="expression">The expression.</param>
        /// <returns></returns>
        public static bool UserCan(FolderType folderType, Expression<Func<Group, bool>> expression)
        {
            if (folderType == null)
                return false;

            if (CurrentUser == null)
                return false;

            FolderTypeComparer L_oFolderTypeComparer = new FolderTypeComparer();
            foreach (Group grp in CurrentUser.GroupList)
            {
                if (grp.FolderTypeRigthList.Contains(folderType, L_oFolderTypeComparer))
                {
                    bool result = (expression.Compile()(grp) || grp.IsAdministrator);
                    if (result)
                        return true;
                }
            }
            return false;
        }

        /// <summary>
        /// CHeck if the current user have rights on the FolderType.
        /// </summary>
        /// <param name="folderType">Type of the folder.</param>
        /// <param name="mode">The mode.</param>
        /// <returns></returns>
        public static bool UserHaveFolderTypeRight(FolderType folderType, AppDisplayMode mode)
        {
            FolderTypeComparer L_oFolderTypeComparer = new FolderTypeComparer();

            foreach (Group userGroup in GlobalWebContext.CurrentUser.GroupList)
            {
                switch (mode)
                {
                    case AppDisplayMode.Search:
                        if ((userGroup.FolderTypeRigthList.Contains(folderType, L_oFolderTypeComparer)) &&
                            ((userGroup.CanReorganize || userGroup.CanConsult)))
                        {
                            return true;
                        }
                        break;
                    case AppDisplayMode.Import:
                    case AppDisplayMode.Flow:
                        if ((userGroup.FolderTypeRigthList.Contains(folderType, L_oFolderTypeComparer)) &&
                            ((userGroup.CanScann || userGroup.CanMassImport)))
                        {
                            return true;
                        }
                        break;
                    case AppDisplayMode.Admin:
                        if ((userGroup.FolderTypeRigthList.Contains(folderType, L_oFolderTypeComparer)) &&
                            ((userGroup.IsAdministrator)))
                        {
                            return true;
                        }
                        break;
                    case AppDisplayMode.None:
                    default:
                        throw new NotImplementedException();
                        // break;
                }
            }

            return false;
        }

        #endregion
    }

}